package com.server.commons.file.base;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import com.server.model.all.enums.BucketNameEnum;
import com.server.common.code.error.BusinessException;
import com.server.common.code.utils.ImageUtils;
import com.server.common.code.utils.OptionalUtils;
import com.server.commons.file.interfaces.FileInterface;
import com.server.commons.file.model.input.UpLoadImageInput;
import com.server.commons.file.model.input.UpdateFileInput;
import com.server.commons.file.model.input.UpdateImageInput;
import com.server.commons.file.model.input.UploadFileInput;
import com.server.commons.file.model.output.UpLoadImageOutput;
import com.server.commons.file.model.output.UploadFileOutput;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.ObjectUtils;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.InputStream;
import java.util.UUID;

/**
 * 所有文件的框架
 * @author LXC
 * @date 2023/2/6 10:08
 */
@Slf4j
public abstract class BaseFile implements FileInterface {

    public static final String GLOBAL = "global";

    //获取桶名
    public abstract BucketNameEnum getBucketNameEnum();

    //桶的权限
    public abstract String getPolicy();

    /**
     * 上传缩略图
     * @author LXC
     * @date 2023/2/6 15:14
     */
    @Override
    public UpLoadImageOutput upLoadThumbnailImage(UpLoadImageInput upLoadImageInput, Integer scaleSize) {
        String suffix = "jpg";
        String fileName = UUID.randomUUID().toString()+"."+suffix;
        File file = FileUtil.file(fileName);

        try{
            Image image = ImageUtils.createThumbnail(upLoadImageInput.getBytes(),scaleSize);
            ImageUtils.write(image,file);
            upLoadImageInput.setBytes(FileUtil.readBytes(file));
            upLoadImageInput.setWidth(image.getWidth(null));
            upLoadImageInput.setHeight(image.getHeight(null));
            upLoadImageInput.setSuffix(suffix);
            return uploadImage(upLoadImageInput);
        } catch (Exception e) {
            log.error("上传失败",e);
        }finally {
            FileUtil.del(file);
        }
        throw new BusinessException("缩略图上传失败");
    }

    /**
     * 上传主图
     * @author LXC
     * @date 2023/2/6 15:14
     */
    @Override
    public UpLoadImageOutput upLoadMainImage(UpLoadImageInput upLoadImageInput) {
        upLoadImageInput.setWidth(null);
        upLoadImageInput.setHeight(null);
        return uploadImage(upLoadImageInput);
    }

    @Override
    public UploadFileOutput uploadFile(UploadFileInput uploadFileInput) {
        UploadFileOutput uploadFileOutput = new UploadFileOutput();
        String bucketName = getBucketNameEnum().getName();

        OptionalUtils.ofEmpty(uploadFileInput.getBusinessNameEnum()).orElseThrow(()->new BusinessException("上传格式错误"));
        OptionalUtils.ofEmpty(uploadFileInput.getSuffix()).orElseThrow(()->new BusinessException("上传格式错误"));
        OptionalUtils.ofEmpty(uploadFileInput.getFileCode()).orElseThrow(()->new BusinessException("上传格式错误"));
        OptionalUtils.ofEmpty(uploadFileInput.getBytes()).orElseThrow(()->new BusinessException("上传格式错误"));

        String path = OptionalUtils.ofEmpty(uploadFileInput.getPath())
                .orElse(uploadFileInput.getFileFullPath());
        uploadFileInput.setPath(path);

        //获取相对路径
        String relativePath = BucketNameEnum.getBucketNameEnum(bucketName).getMapperNgName() +"/"+ path;
        uploadFileOutput.setRelativePath(relativePath);
        uploadFileOutput.setPath(path);
        uploadFileOutput.setBucketName(bucketName);
        uploadFileOutput.setUserCode(uploadFileInput.getUserCode());
        uploadFileOutput.setSize((long) uploadFileInput.getBytes().length);

        return uploadFileOutput;
    }

    /**
     * 上传图片
     * @author LXC
     * @date 2023/2/6 15:14
     */
    @Override
    public UpLoadImageOutput uploadImage(UpLoadImageInput upLoadImageInput) {

        try (InputStream inputStream = IoUtil.toStream(upLoadImageInput.getBytes())){
            BufferedImage bufferedImage = ImageUtils.read(inputStream);

            UploadFileOutput uploadFileOutput = uploadFile(upLoadImageInput);
            UpLoadImageOutput upLoadImageOutput = BeanUtil.copyProperties(uploadFileOutput, UpLoadImageOutput.class);
            upLoadImageOutput.setWidth(bufferedImage.getWidth());
            upLoadImageOutput.setHeight(bufferedImage.getHeight());
            upLoadImageOutput.setFileCode(upLoadImageInput.getFileCode());
            return upLoadImageOutput;
        }catch (Exception e){
            log.error("上传失败",e);
        }
        throw new BusinessException("上传失败");
    }

    /**
     * 更新图片
     * @author LXC
     * @date 2023/2/6 15:14
     */
    @Override
    public UploadFileOutput updateImage(UpdateImageInput updateImageInput) {
        UploadFileOutput uploadFileOutput = uploadImage(updateImageInput);

        if(ObjectUtils.isEmpty(uploadFileOutput)){
            throw new BusinessException("文件上传失败");
        }

        if(!deleteFile(updateImageInput.getOldPaths())){
            throw new BusinessException("文件删除失败");
        }

        return uploadFileOutput;
    }

    /**
     * 更新文件
     * @author LXC
     * @date 2023/2/7 8:29
     */
    @Override
    public UploadFileOutput updateFile(UpdateFileInput updateFileInput) {
        UploadFileOutput uploadFileOutput = uploadFile(updateFileInput);

        if(ObjectUtils.isEmpty(uploadFileOutput)){
            throw new BusinessException("文件上传失败");
        }

        if(!deleteFile(updateFileInput.getOldPaths())){
            throw new BusinessException("文件删除失败");
        }

        return uploadFileOutput;
    }

}
